#pragma once
#include <vector>
#include "mbt/object3d.hh"
#include "mbt/tclc_histograms.hh"
#include "mbt/wtclc_histograms.hh"

class View;
class SearchLine;

class BundleHist {
public:
	BundleHist(const std::vector<Object3D*>& objs);

	virtual ~BundleHist() = 0;

	virtual void Update(cv::Mat& frame, cv::Mat& mask_map, cv::Mat& depth_map, int oid, float afg, float abg)  = 0;
	virtual void GetPixelProb(uchar rc, uchar gc, uchar bc, int x, int y, int oid, float& ppf, float& ppb) {}
	virtual void GetBundleProb(SearchLine* search_line, const cv::Mat& frame, int oid) = 0;
	virtual void GetRegionProb(const cv::Mat& frame, int oid, cv::Mat& prob_map) = 0;

protected:
	View* view;
	std::vector<Object3D*> objs;
};

class RBOTHist : public BundleHist {
public:
	RBOTHist(const std::vector<Object3D*>& objects);

	virtual void Update(cv::Mat& frame, cv::Mat& mask_map, cv::Mat& depth_map, int oid, float afg, float abg) override;
	virtual void GetPixelProb(uchar rc, uchar gc, uchar bc, int x, int y, int oid, float& ppf, float& ppb) override;
	virtual void GetBundleProb(SearchLine* search_line, const cv::Mat& frame, int oid) override;
	virtual void GetRegionProb(const cv::Mat& frame, int oid, cv::Mat& prob_map) override;

protected:

};

class TCLCHist : public RBOTHist {
public:
	TCLCHist(const std::vector<Object3D*>& objects);

	//virtual void Update(cv::Mat& frame, cv::Mat& mask_map, cv::Mat& depth_map, int oid, float afg, float abg) override;
	//virtual void GetBundleProb(SearchLine* search_line, const cv::Mat& frame, int oid) override;
	//virtual void GetRegionProb(const cv::Mat& frame, int oid, cv::Mat& prob_map) override;
};

class WTCLCHist : public BundleHist {
public:
	WTCLCHist(const std::vector<Object3D*>& objects);

	virtual void Update(cv::Mat& frame, cv::Mat& mask_map, cv::Mat& depth_map, int oid, float afg, float abg) override;
	virtual void GetBundleProb(SearchLine* search_line, const cv::Mat& frame, int oid) override;
	virtual void GetRegionProb(const cv::Mat& frame, int oid, cv::Mat& prob_map) override;

protected:
	void ComputeHistWeight();
	void MatchCenters(std::vector<cv::Point>& cur_centers, std::vector<cv::Point2f>& pre_centers, std::vector<int>& match_ids);
	void GetBundleProbAll(SearchLine* search_line, const cv::Mat& frame, int oid);
	void GetBundleProbWeighted(SearchLine* search_line, const cv::Mat& frame, int oid);

protected:
	std::vector<LocalHist32> hists;
	std::vector<cv::Point> centers;
	std::vector<cv::Point3f> centers3d;

	int hrad;
	int offset;
	int srad;
};

class TestHist : public BundleHist {
public:
	TestHist(const std::vector<Object3D*>& objects);

	virtual void Update(cv::Mat& frame, cv::Mat& mask_map, cv::Mat& depth_map, int oid, float afg, float abg) override;
	virtual void GetBundleProb(SearchLine* search_line, const cv::Mat& frame, int oid) override;
	virtual void GetRegionProb(const cv::Mat& frame, int oid, cv::Mat& prob_map) override;

protected:
	LocalHist32 hist;
};